package com.runner.screen;

import java.util.ArrayList;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.Camera;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.NinePatch;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator;
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator.FreeTypeFontParameter;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.ui.ImageButton;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton.TextButtonStyle;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.runner.RedRunner;
import com.runner.observer.Event;
import com.runner.observer.Subject;
import com.runner.sound.AudioManager;
import com.runner.track.CloudManager;
import com.runner.utility.Constants;
import com.runner.utility.Locator;

public class MenuScreen implements Screen, Constants {
	private BitmapFont textFont, titleFont, runnerFont, smallFont;
	private Stage stage;
	private Table table;
	private TextButton buttonExit, buttonPlay;
	private Label heading;
	private Skin skin;
	private TextureAtlas atlas;
	private TextButtonStyle textButtonStyle, playStyle, exitStyle;
	private ImageButton buttonLeaderboard, buttonAchv, buttonSignIn, buttonSignOut;
	private final ArrayList<TransitionEffect> effects;
	private Texture background;
	private SpriteBatch uiBatch, gameBatch;
	private ImageButton mute, unmute;
	private final Subject subject;
	private final AudioManager audio;
	private ParameterScreen parameterScreen;
	private NinePatch buttonPatch;
	private boolean isParamScreen;
	private CloudManager cloudManager;
	public static int COUNT = 1;

	public MenuScreen(final RedRunner game, AudioManager aud, final Subject sub, Camera camera) {
		this.subject = sub;
		this.audio = aud;
		Locator.setOverallGameSpeed(1);
		
		cloudManager = new CloudManager(25);
		cloudManager.generatePresetClouds();
		
		isParamScreen = false;
		buttonPatch = new NinePatch(Locator.getAssets().get(PANEL_PATH, Texture.class));
		stage = new Stage(Locator.getViewport());
		uiBatch = new SpriteBatch();
		gameBatch = new SpriteBatch();
		gameBatch.setProjectionMatrix(camera.combined);

		background = new Texture(BACKGROUNDMAIN_RINGER);

		FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal(FONT));
		FreeTypeFontParameter param = new FreeTypeFontParameter();
		param.size = (int) (96);
		titleFont = generator.generateFont(param);

		param.size = (int) (64);
		textFont = generator.generateFont(param);

		param.size = (int) (28);
		smallFont = generator.generateFont(param);

		param.size = (int) (48);
		BitmapFont cofirmFont = generator.generateFont(param);

		param.size = (int) (40);
		runnerFont = generator.generateFont(param);
		generator.dispose();

		atlas = new TextureAtlas(Gdx.files.internal("data/button.pack"));
		skin = new Skin(atlas);
		table = new Table(skin);
		table.setBounds(0, 0, ACTUAL_VIRTUAL_WIDTH, ACTUAL_VIRTUAL_HEIGHT);

		textButtonStyle = new TextButtonStyle();
		textButtonStyle.up = skin.getDrawable("button.up");
		textButtonStyle.down = skin.getDrawable("button.down");
		textButtonStyle.pressedOffsetX = 1;
		textButtonStyle.pressedOffsetY = -1;
		textButtonStyle.font = textFont;
		playStyle = new TextButtonStyle(textButtonStyle);
		playStyle.fontColor = Color.DARK_GRAY;
		exitStyle = new TextButtonStyle(textButtonStyle);
		exitStyle.fontColor = Color.DARK_GRAY;

		// create a transition screen
		effects = new ArrayList<TransitionEffect>();
		effects.add(new FadeOutTransitionEffect(0.5f));
		effects.add(new FadeInTransitionEffect(0.5f));

		createButtons();
		createMuteButtons();
		createServiceButtons();

		parameterScreen = new ParameterScreen(game, this, smallFont, runnerFont, textFont, cofirmFont, subject);

		// create title
		LabelStyle headingStyle = new LabelStyle(titleFont, Color.DARK_GRAY);
		heading = new Label("Blockland Runner", headingStyle);

		heading.setPosition(ACTUAL_VIRTUAL_WIDTH * 0.08f, ACTUAL_VIRTUAL_HEIGHT * 0.80f);

		buttonPlay.setPosition(ACTUAL_VIRTUAL_WIDTH * 0.1f, ACTUAL_VIRTUAL_HEIGHT * 0.6f);
		buttonExit.setPosition(ACTUAL_VIRTUAL_WIDTH * 0.1f, ACTUAL_VIRTUAL_HEIGHT * 0.36f);

		buttonSignIn.setPosition(ACTUAL_VIRTUAL_WIDTH * 0.82f, ACTUAL_VIRTUAL_HEIGHT * 0.60f);
		buttonSignOut.setPosition(ACTUAL_VIRTUAL_WIDTH * 0.82f, ACTUAL_VIRTUAL_HEIGHT * 0.60f);
		buttonLeaderboard.setPosition(ACTUAL_VIRTUAL_WIDTH * 0.82f, ACTUAL_VIRTUAL_HEIGHT * 0.42f);
		buttonAchv.setPosition(ACTUAL_VIRTUAL_WIDTH * 0.82f, ACTUAL_VIRTUAL_HEIGHT * 0.24f);
		stage.addActor(buttonPlay);
		stage.addActor(buttonSignIn);
		stage.addActor(buttonSignOut);
		stage.addActor(buttonExit);
		stage.addActor(heading);
		stage.addActor(mute);
		stage.addActor(unmute);
		stage.addActor(buttonLeaderboard);
		stage.addActor(buttonAchv);

		if (Locator.isMute()) {
			mute();
		} else {
			unmute();
		}

		subject.notify(Event.EVENT_START_MENU);

		Gdx.input.setInputProcessor(stage);

		if (!Locator.getServices().isUpdated()) {
			switchText(Locator.getServices().isSignedIn());
		}
		
		/*stage.setViewport(Locator.getViewport());
		uiBatch.setTransformMatrix(Locator.getCamera().view);*/
	}

	public void mute() {
		mute.setVisible(true);
		mute.setDisabled(false);
		unmute.setDisabled(true);
		unmute.setVisible(false);
		Locator.writeSave();
	}

	public void unmute() {
		mute.setDisabled(true);
		mute.setVisible(false);
		unmute.setDisabled(false);
		unmute.setVisible(true);
		Locator.writeSave();
	}

	public void reset() {
		parameterScreen.reset();
	}

	@Override
	public void render(float delta) {
		Gdx.gl.glClearColor(0.0f, 0.0f, 0.0f, 1);
		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
		
		uiBatch.setTransformMatrix(stage.getCamera().view);
		uiBatch.setProjectionMatrix(stage.getCamera().projection);
		
		uiBatch.begin();
		uiBatch.draw(background, 0, 0, 0, 0, background.getWidth(), background.getHeight(), 1, 1, 0,
				0, 0, (int) background.getWidth(), (int) background.getHeight(), false, false);
		uiBatch.end();
		
		//render clouds after background, and before text
		gameBatch.begin();
		cloudManager.render(gameBatch);
		gameBatch.end();
		
		uiBatch.begin();
		buttonPatch.draw(uiBatch, ACTUAL_VIRTUAL_WIDTH * 0.08f, ACTUAL_VIRTUAL_HEIGHT * 0.58f, ACTUAL_VIRTUAL_WIDTH * 0.125f,
				ACTUAL_VIRTUAL_HEIGHT * 0.14f);
		buttonPatch.draw(uiBatch, ACTUAL_VIRTUAL_WIDTH * 0.08f, ACTUAL_VIRTUAL_HEIGHT * 0.34f, ACTUAL_VIRTUAL_WIDTH * 0.115f,
				ACTUAL_VIRTUAL_HEIGHT * 0.14f);
		uiBatch.end();

		if (!isParamScreen) {
			stage.act(delta);
			stage.draw();
		} else {
			parameterScreen.render(delta);
		}
		Locator.getEvents().update(delta);
		cloudManager.update(delta);
		
		Locator.getWorld().step(1 / 60f, 6, 2);

	}

	public void switchToParamScreen() {
		isParamScreen = true;
		Gdx.input.setInputProcessor(null);

		parameterScreen.show();
	}

	public void showMenuScreen() {
		isParamScreen = false;
		Gdx.input.setInputProcessor(stage);
	}

	@Override
	public void resize(int width, int height) {
		stage.getViewport().update(width, height, true);
		table.invalidateHierarchy();
		table.setSize(width, height);
	}

	@Override
	public void show() {
		// showMenuScreen();
		effects.clear();
		effects.add(new FadeOutTransitionEffect(0.5f));
		effects.add(new FadeInTransitionEffect(0.5f));
	}

	@Override
	public void hide() {
		Gdx.input.setInputProcessor(null);
	}

	private void createButtons() {
		// create buttons
		buttonPlay = new TextButton("Play", playStyle);
		buttonPlay.addListener(new ClickListener() {
			@Override
			public void clicked(InputEvent event, float x, float y) {
				subject.notify(Event.EVENT_CLICK);
				Locator.setDifficutly(Locator.EASY);
				Locator.getDevice().loadoutScreen();
				switchToParamScreen();
			}
		});
		buttonPlay.pad(10.0f);

		buttonExit = new TextButton("Exit", exitStyle);
		buttonExit.addListener(new ClickListener() {
			@Override
			public void clicked(InputEvent event, float x, float y) {
				subject.notify(Event.EVENT_CLICK);
				Locator.writeSave();
				Gdx.app.exit();
			}
		});
		buttonExit.pad(10.0f);

	}

	private void createMuteButtons() {
		Image i = new Image(new Texture(Gdx.files.internal(MUTE)));
		mute = new ImageButton(i.getDrawable());
		mute.addListener(new ClickListener() {
			@Override
			public void clicked(InputEvent event, float x, float y) {
				audio.unmute();
				subject.notify(Event.EVENT_CLICK);
				unmute();
			}
		});
		mute.setPosition(ACTUAL_VIRTUAL_WIDTH * 0.85f, ACTUAL_VIRTUAL_HEIGHT * 0.855f);
		mute.setScale(2, 2);
		mute.getImage().setScale(2, 2);

		i = new Image(new Texture(Gdx.files.internal(UNMUTE)));
		unmute = new ImageButton(i.getDrawable());
		unmute.addListener(new ClickListener() {
			@Override
			public void clicked(InputEvent event, float x, float y) {
				audio.mute();
				mute();
			}
		});
		unmute.setPosition(ACTUAL_VIRTUAL_WIDTH * 0.85f, ACTUAL_VIRTUAL_HEIGHT * 0.85f);
		unmute.setScale(2 , 2 );
		unmute.getImage().setScale(2 , 2 );

	}

	public void createServiceButtons() {
		buttonSignIn = new ImageButton(new Image(Locator.getAssets().get(SIGN_IN, Texture.class)).getDrawable());
		buttonSignIn.setScale(1f );
		buttonSignIn.getImage().setScale(1f );
		buttonSignIn.addListener(new ClickListener() {
			@Override
			public void clicked(InputEvent event, float x, float y) {
				Locator.getDevice().googleLogIn();
			}

		});

		buttonSignOut = new ImageButton(new Image(Locator.getAssets().get(SIGN_OUT, Texture.class)).getDrawable());
		buttonSignOut.setScale(1f );
		buttonSignOut.getImage().setScale(1f );
		buttonSignOut.addListener(new ClickListener() {
			@Override
			public void clicked(InputEvent event, float x, float y) {
				Locator.getDevice().googleLogOff();
			}

		});

		buttonAchv = new ImageButton(new Image(Locator.getAssets().get(ACHIEVEMENT, Texture.class)).getDrawable());
		buttonAchv.setScale(0.8f );
		buttonAchv.getImage().setScale(0.8f );
		buttonAchv.addListener(new ClickListener() {
			@Override
			public void clicked(InputEvent event, float x, float y) {
				Locator.getDevice().showAchievements();
			}

		});

		buttonLeaderboard = new ImageButton(new Image(Locator.getAssets().get(LEADERBOARD, Texture.class)).getDrawable());
		buttonLeaderboard.setScale(0.8f );
		buttonLeaderboard.getImage().setScale(0.8f );
		buttonLeaderboard.addListener(new ClickListener() {
			@Override
			public void clicked(InputEvent event, float x, float y) {
				Locator.getDevice().showLeaderboardScore();
			}

		});
	}

	public void switchText(boolean didSignIn) {
		if (didSignIn) {
			buttonSignOut.setVisible(true);
			buttonSignOut.setDisabled(false);
			buttonSignIn.setDisabled(true);
			buttonSignIn.setVisible(false);
		} else {
			buttonSignIn.setVisible(true);
			buttonSignIn.setDisabled(false);
			buttonSignOut.setDisabled(true);
			buttonSignOut.setVisible(false);
		}
	}

	@Override
	public void pause() {
	}

	@Override
	public void resume() {
	}

	@Override
	public void dispose() {
		stage.dispose();
		atlas.dispose();
		skin.dispose();
	}

}